package ee.ut.maxorato_macobo.oop.mud.items;

import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Scanner;

import ee.ut.maxorato_macobo.oop.mud.GameMain;
import ee.ut.maxorato_macobo.oop.mud.game.DataParser;
import ee.ut.maxorato_macobo.oop.mud.game.GameRoom;
import ee.ut.maxorato_macobo.oop.mud.game.GameUtils;
import ee.ut.maxorato_macobo.oop.mud.game.PlayerCharacter;

public class ItemCorpse extends ItemBase implements ContainsItems {
	private ArrayList<ItemBase> contents;
	private ItemCorpseTemplate itemTemplate;
	private boolean corpseLocked;
	private boolean hasCustomCrumbleTime;
	private int crumbleTime;
	private long crumbleStart;
	
	public ItemCorpse(ItemTemplate newItemTemplate, ContainsItems newItemLocation) {
		super(newItemTemplate, newItemLocation);
		
		checkInitCrumble();
		
		hasCustomCrumbleTime = false;
		crumbleTime = 100;
		
		corpseLocked = false;
		
		contents = new ArrayList<ItemBase>();
		itemTemplate = (ItemCorpseTemplate)newItemTemplate;
		
		ItemProcessorPool.registerItem(this);
	}
	
	@Override
	public void moveToLocation(ContainsItems newItemLocation) {
		super.moveToLocation(newItemLocation);
		
		checkInitCrumble();
	}
	
	@Override
	public void destroyItem() {
		ArrayList<ItemBase> itemList = new ArrayList<ItemBase>(contents);
		
		for(ItemBase item : itemList) {
			item.destroyItem();
		}
		
		super.destroyItem();
	}
	
	public void parseExtraSection(Scanner parser) {
		while(parser.hasNextLine()) {
			String[] parts = parser.nextLine().trim().split(" ", 2);
			
			if(parts[0].equals("sub")) {
				if(parts[1].equals("itemi")) {
					ItemBase subItem = DataParser.parseItemInstInfo(parser, true);
					
					if(subItem != null) {
						subItem.moveToLocation(this);
					}
				}
				else if(parts[1].equals("crumbletime")) {
					hasCustomCrumbleTime = true;
					crumbleTime = Math.max(0, GameUtils.properIntParser(parts[1]));
				}
				else {
					DataParser.parseDummy(parser);
				}
			}
			else if(parts[0].equals("end")) {
				break;
			}
		}
	}
	
	public void describeForPlayer(PlayerCharacter player) {
		player.sendTickMessage(getLookString() + "\r\n" + getDescription());
		
		player.sendTickMessage("\r\nIt contains the following items:");
		GameUtils.describeItemListForPlayer(player, getItemList(), false);
	}
	
	@Override
	public ItemBase clone() {
		ItemCorpse corpse = new ItemCorpse(itemTemplate, itemLocation);
		
		ArrayList<ItemBase> itemList = new ArrayList<ItemBase>(getItemList());
		
		for(ItemBase item : itemList) {
			item.clone().moveToLocation(corpse);
		}
		
		if(corpseLocked) corpse.lockCorpse();
		if(hasCustomCrumbleTime) corpse.setCrumbleTime(crumbleTime);

		return corpse;
	}

	public ArrayList<ItemBase> getItemList() {
		return contents;
	}
	
	public void lockCorpse() {
		corpseLocked = true;
	}
	
	public String canAddItem(ItemBase item) {
		if(corpseLocked) return "You can't put items into a corpse.";
		else return null;
	}
	
	public void itemAdd(ItemBase item) {
		if(canAddItem(item) == null && !contents.contains(item)) {
			contents.add(item);
		}
	}
	
	public void itemRemove(ItemBase item) {
		if(contents.contains(item)) {
			contents.remove(item);
		}
	}
	
	public ItemBase findItemByName(String itemName) {
		return findItemByName(itemName, 1);
	}
	
	public ItemBase findItemByName(String itemName, int index) {
		ListIterator<ItemBase> it = getItemList().listIterator();
		int matchCount = 0;
		
		while(it.hasNext()) {
			ItemBase item = it.next();
			
			if(item.getName().compareToIgnoreCase(itemName) == 0) {
				
				if(++matchCount == index) {
					return item;
				}
			}
		}
		
		return null;
	}
	
	public int getWeight() {
		int weight = itemTemplate.getWeight();
		
		ListIterator<ItemBase> it = contents.listIterator();
		
		while(it.hasNext()) {
			weight += it.next().getWeight();
		}
		
		return weight;
	}
	
	public void setCrumbleTime(int newCrumbleTime) {
		hasCustomCrumbleTime = true;
		crumbleTime = newCrumbleTime;
	}
	
	public int getCrumbleTime() {
		if(hasCustomCrumbleTime) return crumbleTime;
		else return itemTemplate.getCrumbleTime();
	}
	
	public void checkInitCrumble() {
		if(itemLocation != null && itemLocation instanceof GameRoom) {
			crumbleStart = GameMain.getTickNanoTime();
		}
		else {
			crumbleStart = 0L;
		}
	}
	
	public void crumbleThis() {
		if(itemLocation instanceof GameRoom) {
			for(PlayerCharacter player : ((GameRoom)itemLocation).getRoomPlayerList()) {
				player.sendTickMessage(GameUtils.stringCapitalize(getLongName()) + " crumbles into dust.");
			}
			
			destroyItem();
		}
	}
	
	public void processTick() {
		if(crumbleStart != 0L) {
			if(crumbleStart + 1000000000L * (long)getCrumbleTime() < GameMain.getTickNanoTime()) {
				crumbleThis();
			}
		}
	}
}
